﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using NesGfx;
namespace cnetmegamanprj
{
    public partial class TileEditor : Form
    {
        readonly int tileWidth = 8, tileHeight = 8, tileSize = 16;
        Bitmap main, edit = new Bitmap(64, 64), original = new Bitmap(64, 64);
        byte[] originalBuf = new byte[16];
        Render render, renderEdit, renderOriginal;
        TileEditData d;
        int currentIndex = 0, currentTileOffset = 0;
        uint currentColor = 0;
        static readonly int mainMutiply = 4, editMultiply = 8, originalMultiply = editMultiply;

        public TileEditor(TileEditData data)
        {
            InitializeComponent();
            d = data;
            main = new Bitmap(d.c * tileWidth * mainMutiply, d.r * tileHeight * mainMutiply);
            render = new Render(d.buf, main, mainMutiply);
            renderEdit = new Render(d.buf, edit, editMultiply);
            renderOriginal = new Render(originalBuf, original, originalMultiply);
        }

        void drawMain()
        {
            var m = mainMutiply;
            render.lockIt();
            for (int y = 0; y < d.r; y++)
            {
                for (int x = 0; x < d.c; x++)
                {
                    render.Draw(getTile(y * d.c + x), x * tileWidth * m, y * tileHeight * m);
                }
            }
            render.unlockIt();
            pictureBox1.Invalidate();
        }
        void drawMain(int i)
        {
            drawMain(i % d.c, i / d.c);
        }

        int getTile(int i)
        {
            return d.map == null ? i : d.map[i];
        }
        void drawMain(int x, int y)
        {
            var m = mainMutiply;

            render.Draw(getTile(y * d.c + x), x * tileWidth * m, y * tileHeight * m);
            pictureBox1.Invalidate();
        }

        void drawEdit()
        {
            renderEdit.Draw(currentTileOffset, 0, 0);
            pictureBox2.Invalidate();
        }
        void drawOriginal()
        {
            renderOriginal.Draw(0, 0, 0);
            pictureBox3.Invalidate();
        }
        void switchIndex(int i)
        {
            currentIndex = i;
            currentTileOffset = getTile(i);
            //i know currentTileOffset * tileSize looks wrong but it isnt
            Buffer.BlockCopy(d.buf, currentTileOffset * tileSize, originalBuf, 0, 16);
            drawEdit();
            drawOriginal();
        }
        void fillColor(PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;

            int w = pictureBox4.Width / 4;
            int h = pictureBox4.Height;

            Color c = Color.FromArgb((int)render.pal.rgbPalette[0]);
            Brush brush = new SolidBrush(c);
            graphics.FillRectangle(brush, new Rectangle(0, 0, w, h));

            c = Color.FromArgb((int)render.pal.rgbPalette[1]);
            brush = new SolidBrush(c);
            graphics.FillRectangle(brush, new Rectangle(w * 1, 0, w, h));

            c = Color.FromArgb((int)render.pal.rgbPalette[2]);
            brush = new SolidBrush(c);
            graphics.FillRectangle(brush, new Rectangle(w * 2, 0, w, h));

            c = Color.FromArgb((int)render.pal.rgbPalette[3]);
            brush = new SolidBrush(c);
            graphics.FillRectangle(brush, new Rectangle(w * 3, 0, w, h));

        }
        private void TileEditor_Load(object sender, EventArgs e)
        {
            pictureBox1.Image = main;
            pictureBox2.Image = edit;
            pictureBox3.Image = original;
            pictureBox1.Width = main.Width;
            pictureBox1.Height = main.Height;

            pictureBox2.Left = pictureBox1.Right + 6;
            pictureBox4.Left = pictureBox1.Right + 6;
            pictureBox3.Left = pictureBox2.Right + 6;
            this.Width = pictureBox3.Right + 20;
            this.Height = pictureBox1.Bottom + 60;

            switchIndex(0);
            drawMain();
            drawEdit();
            drawOriginal();
            pictureBox1.Invalidate();
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            var x = e.X / (tileWidth * mainMutiply);
            var y = e.Y / (tileHeight * mainMutiply);
            switchIndex(y * d.c + x);
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox3_DoubleClick(object sender, EventArgs e)
        {
            //i know currentTileOffset * tileSize looks wrong but it isnt
            Buffer.BlockCopy(originalBuf, 0, d.buf, currentTileOffset * tileSize, tileSize);
            drawEdit();
            drawMain(currentIndex);
        }
        private void pictureBox2_MouseClick(object sender, MouseEventArgs e)
        {
            var x = e.X / editMultiply;
            var y = e.Y / editMultiply;

            if (e.Button == MouseButtons.Left)
            {
                renderEdit.tile[y, x] = currentColor;
                drawEdit();
                drawMain(currentIndex);
            }
            else
                currentColor = renderEdit.tile[y, x];
            //this.Text = string.Format("{0} {1} {2}", x, y, currentColor);
        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox4_Paint(object sender, PaintEventArgs e)
        {
            fillColor(e);
        }

        private void pictureBox4_MouseClick(object sender, MouseEventArgs e)
        {
            currentColor = (uint)(e.X / (pictureBox4.Width / 4));
        }

        private void TileEditor_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape) this.Close();
        }
    }

}
